<template>
  <div class="widget-form-container">
    <div v-if="data.list.length == 0" class="form-empty">从左侧拖拽来添加字段</div>
    <a-form
      :size="data.config.size"
      label-suffix=":"
      :layout="data.config.formLayout"
      :wrapperCol="data.config.formLayout == 'horizontal' ? { span: data.config.wrapperCol.span } : {}"
      :labelCol="data.config.formLayout == 'horizontal' ? { span: data.config.labelCol.span } : {}"
      :labelAlign="data.config.labelPosition"
    >
      <!--  :labelCol="data.config.labelCol" :wrapperCol="data.config.wrapperCol" -->
      <draggable
        class=""
        v-model="data.list"
        v-bind="{
          group: 'people',
          ghostClass: 'ghost',
          animation: 200,
          handle: '.drag-widget'
        }"
        @end="handleMoveEnd"
        @add="handleWidgetAdd"
      >
        <transition-group name="fade" tag="div" class="widget-form-list">
          <div v-for="(element, index) in data.list" :key="element.key">
            <template v-if="element.type == 'grid'">
              <a-row
                class="widget-col widget-view"
                v-if="element && element.key"
                :key="element.key"
                type="flex"
                :class="{ active: selectWidget.key == element.key }"
                :gutter="element.options.gutter ? element.options.gutter : 0"
                :justify="element.options.justify"
                :align="element.options.align"
                @click.native="handleSelectWidget(index)"
              >
                <a-col v-for="(col, colIndex) in element.columns" :key="colIndex" :span="col.span ? col.span : 0">
                  <draggable
                    v-model="col.list"
                    :no-transition-on-drag="true"
                    v-bind="{
                      group: 'people',
                      ghostClass: 'ghost',
                      animation: 200,
                      handle: '.drag-widget'
                    }"
                    @end="handleMoveEnd"
                    @add="handleWidgetColAdd($event, element, colIndex)"
                  >
                    <transition-group name="fade" tag="div" class="widget-col-list">
                      <div v-for="(el, i) in col.list" :key="el.key">
                        <widget-form-item v-if="el.key" :element="el" :select.sync="selectWidget" :index="i" :data="col"></widget-form-item>
                      </div>
                    </transition-group>
                  </draggable>
                </a-col>
                <div class="widget-view-action widget-col-action" v-if="selectWidget.key == element.key">
                  <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)"></i>
                </div>

                <div class="widget-view-drag widget-col-drag" v-if="selectWidget.key == element.key">
                  <i class="iconfont icon-drag drag-widget"></i>
                </div>
              </a-row>
            </template>
            <template v-else-if="element.type == 'tabs' && selectWidget != null">
              <div @click="handleSelectWidget(index)" :class="{ active: selectWidget.key == element.key }" class="widget-col widget-view" :key="element.key">
                <a-tabs v-model="element.active" v-if="element && element.key" :type="element.options.type" :tabPosition="element.options.tabPosition">
                  <a-tab-pane v-for="(tab, tab_index) in element.columns" :tab="tab.label" :name="tab.name" :key="tab.name" forceRender>
                    <draggable
                      v-model="tab.list"
                      :no-transition-on-drag="true"
                      v-bind="{
                        group: 'people',
                        ghostClass: 'ghost',
                        animation: 200,
                        handle: '.drag-widget'
                      }"
                      @end="handleMoveEnd"
                      @add="handleWidgetTabAdd($event, element, tab_index, tab.name)"
                    >
                      <transition-group name="fade" tag="div" class="widget-col-list">
                        <div v-for="(tabItem, i) in tab.list" :key="tabItem.key">
                          <widget-form-item v-if="tabItem.key" :element="tabItem" :select.sync="selectWidget" :index="i" :data="tab"></widget-form-item>
                        </div>
                      </transition-group>
                    </draggable>
                  </a-tab-pane>
                </a-tabs>
                <div class="widget-view-action widget-col-action" v-if="selectWidget.key == element.key">
                  <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)"></i>
                </div>

                <div class="widget-view-drag widget-col-drag" v-if="selectWidget.key == element.key">
                  <i class="iconfont icon-drag drag-widget"></i>
                </div>
              </div>
            </template>

            <!-- <template v-else-if="element.type == 'html'">
              <div @click="handleSelectWidget(index)" :class="{active: selectWidget.key == element.key}" class="widget-col widget-view" v-if="element && element.key"  :key="element.key">
                <div v-html="element.options.defaultValue"></div>
              </div>
            </template>  -->

            <template v-else-if="element.type == 'divider'">
              <div @click="handleSelectWidget(index)" :class="{ active: selectWidget.key == element.key }" class="widget-col widget-view" v-if="element && element.key" :key="element.key">
                <a-divider orientation="left">{{ element.name }}</a-divider>
                <div class="widget-view-action widget-col-action" v-if="selectWidget.key == element.key">
                  <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)"></i>
                </div>

                <div class="widget-view-drag widget-col-drag" v-if="selectWidget.key == element.key">
                  <i class="iconfont icon-drag drag-widget"></i>
                </div>
              </div>
            </template>
            <template v-else>
              <widget-form-item v-if="element && element.key" :key="element.key" :element="element" :select.sync="selectWidget" :index="index" :data="data"></widget-form-item>
            </template>
          </div>
        </transition-group>
      </draggable>
    </a-form>
  </div>
</template>

<script>
import Draggable from 'vuedraggable'
import WidgetFormItem from './WidgetFormItem'

export default {
  components: {
    Draggable,
    WidgetFormItem
  },
  props: ['data', 'select'],
  data() {
    return {
      selectWidget: this.select
    }
  },
  mounted() {
    document.body.ondrop = function (event) {
      let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
      if (isFirefox) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
  },
  methods: {
    handleMoveEnd({ newIndex, oldIndex }) {
      console.log('index', newIndex, oldIndex)
    },
    handleSelectWidget(index) {
      this.selectWidget = this.data.list[index]
    },
    handleWidgetAdd(evt) {
      console.log('add', evt)
      console.log('end', evt)
      const newIndex = evt.newIndex
      const to = evt.to
      console.log(to)

      //为拖拽到容器的元素添加唯一 key
      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
      this.$set(this.data.list, newIndex, {
        ...this.data.list[newIndex],
        options: {
          ...this.data.list[newIndex].options,
          remoteFunc: 'func_' + key
        },
        key,
        // 绑定键值
        model: this.data.list[newIndex].type + '_' + key,
        rules: []
      })

      if (this.data.list[newIndex].type === 'radio' || this.data.list[newIndex].type === 'checkbox' || this.data.list[newIndex].type === 'select') {
        this.$set(this.data.list, newIndex, {
          ...this.data.list[newIndex],
          options: {
            ...this.data.list[newIndex].options,
            options: this.data.list[newIndex].options.options.map((item) => ({
              ...item
            }))
          }
        })
      }

      if (this.data.list[newIndex].type === 'grid' || this.data.list[newIndex].type === 'tabs') {
        this.$set(this.data.list, newIndex, {
          ...this.data.list[newIndex],
          columns: this.data.list[newIndex].columns.map((item) => ({ ...item }))
        })
      }

      this.selectWidget = this.data.list[newIndex]
    },
    handleWidgetTabAdd($event, row, tab_index, tab_key) {
      console.log('tab_add', $event, row, tab_index, tab_key)
      if (tab_key != null) {
        row.active = tab_key
      }
      const newIndex = $event.newIndex
      const oldIndex = $event.oldIndex
      const item = $event.item

      console.log('tab_add-index', newIndex, oldIndex)

      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
      // this.$set(.list, newIndex, {
      // item.
      this.$set(row.columns[tab_index].list, newIndex, {
        ...row.columns[tab_index].list[newIndex],
        options: {
          ...row.columns[tab_index].list[newIndex].options
        },
        key,
        // 绑定键值
        model: row.columns[tab_index].list[newIndex].type + '_' + key,
        rules: []
      })
    },

    handleWidgetColAdd($event, row, colIndex) {
      console.log('coladd', $event, row, colIndex)
      const newIndex = $event.newIndex
      const oldIndex = $event.oldIndex
      const item = $event.item

      // 防止布局元素的嵌套拖拽
      if (item.className.indexOf('data-grid') >= 0) {
        // 如果是列表中拖拽的元素需要还原到原来位置
        item.tagName === 'DIV' && this.data.list.splice(oldIndex, 0, row.columns[colIndex].list[newIndex])

        row.columns[colIndex].list.splice(newIndex, 1)

        return false
      }

      console.log('from', item)

      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)

      this.$set(row.columns[colIndex].list, newIndex, {
        ...row.columns[colIndex].list[newIndex],
        options: {
          ...row.columns[colIndex].list[newIndex].options,
          remoteFunc: 'func_' + key
        },
        key,
        // 绑定键值
        model: row.columns[colIndex].list[newIndex].type + '_' + key,
        rules: []
      })

      if (row.columns[colIndex].list[newIndex].type === 'radio' || row.columns[colIndex].list[newIndex].type === 'checkbox' || row.columns[colIndex].list[newIndex].type === 'select') {
        this.$set(row.columns[colIndex].list, newIndex, {
          ...row.columns[colIndex].list[newIndex],
          options: {
            ...row.columns[colIndex].list[newIndex].options,
            options: row.columns[colIndex].list[newIndex].options.options.map((item) => ({
              ...item
            }))
          }
        })
      }

      this.selectWidget = row.columns[colIndex].list[newIndex]
    },
    handleWidgetDelete(index) {
      if (this.data.list.length - 1 === index) {
        if (index === 0) {
          this.selectWidget = {}
        } else {
          this.selectWidget = this.data.list[index - 1]
        }
      } else {
        this.selectWidget = this.data.list[index + 1]
      }

      this.$nextTick(() => {
        this.data.list.splice(index, 1)
      })
    }
  },
  watch: {
    select(val) {
      this.selectWidget = val
    },
    selectWidget: {
      handler(val) {
        this.$emit('update:select', val)
      },
      deep: true
    }
  }
}
</script>
